/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "kh_sle_c_interface_test_entry.h"
#include "kh_sle_connect.h"
#include "kh_sle_host.h"
#include "kh_sle_seek.h"
#include "sle_error_code.h"
#include "sle_unit_test_log.h"
#include <stdlib.h>
#include <cmsis_os2.h>
SleConnectCallbacks *g_sleConnectUtCbs = NULL;
static uint16_t g_connectId;

void OnSleUtConnectStateChanged(uint16_t connectId, const SleDeviceAddress *addr
        , SleConnectState connState, SlePairState pairState, SleDisConnectReason discReason)
{
    SLE_UT_LOG("[KhSleConnectTest][PASSED]OnSleUtConnectStateChanged, connectId=%d, connState=%d, pairState=%d, discReason=%d", connectId, connState, pairState, discReason);
    if(connState == SLE_CONNECT_CONNECTED_STATE) {
        g_connectId = connectId;
    } else {
        g_connectId = 65535;    // invalid value
    }
    return;
}

void OnSleUtRequestConnParamUpdateCallback(uint16_t connectId, SleErrorCode errCode, const SleConnectionParamUpdateEvt *connParam)
{
    SLE_UT_LOG("[KhSleConnectTest][PASSED]OnSleUtRequestConnParamUpdateCallback, connectId=%d, errCode=%d", connectId, errCode);
    return;
}

void InitSleConnectServiceTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleConnectService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]InitSleConnectServiceTestLevel0 failed(%d)", ret);
}

void RegisterConnectCallbackTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = RegisterConnectCallbacks(g_sleConnectUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]RegisterConnectCallbackTestLevel0 failed(%d)", ret);
}

void SleConnectTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;

    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
    };
    ret = SleConnect(&remoteAddr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]SleConnectTestLevel0 failed(%d)", ret);
}

void SendPairReqTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
    };
    ret = SendPairReq(&remoteAddr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]SendPairReqTestLevel0 failed(%d)", ret);
}

void GetDevicePairStateTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
    };
    SlePairState pairState = SLE_PAIR_ERROR_STATE;
    ret = GetDevicePairState(&remoteAddr, &pairState);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]GetDevicePairStateTestLevel0 failed(%d)", ret);
}

void RemovePairTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
    };
    ret = RemovePair(&remoteAddr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]RemovePairTestLevel0 failed(%d)", ret);
}

void ReadRemoteRssiTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    int32_t rssi = 0;
    ret = ReadRemoteRssi(g_connectId, &rssi);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]ReadRemoteRssiTestLevel0 failed(%d)", ret);
}

void SleDisconnectTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
    };
    ret = SleDisconnect(&remoteAddr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]SleDisconnectTestLevel0 failed(%d)", ret);
}

void UnregisterConnectCallbackTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = UnregisterConnectCallbacks(g_sleConnectUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]UnregisterConnectCallbackTestLevel0 failed(%d)", ret);
}

void DeInitSleConnectServiceTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = DeinitSleConnectService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]DeInitSleConnectServiceTestLevel0 failed(%d)", ret);
}

void KhSleConnectTestLevel0(void)
{
    SLE_UT_LOG("___KhSleConnectTestLevel0 start");
    InitSleConnectServiceTestLevel0();
    RegisterConnectCallbackTestLevel0();
    SleConnectTestLevel0();
    sleep(1);
    SendPairReqTestLevel0();
    sleep(1);
    GetDevicePairStateTestLevel0();
    RemovePairTestLevel0();
    sleep(1);
    ReadRemoteRssiTestLevel0();
    SleDisconnectTestLevel0();
    sleep(1);
    UnregisterConnectCallbackTestLevel0();
    DeInitSleConnectServiceTestLevel0();
    SLE_UT_LOG("___KhSleConnectTestLevel0 end");
}

void InitSleConnectServiceTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleConnectService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]InitSleConnectServiceTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = InitSleConnectService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]InitSleConnectServiceTestLevel1 failed2(%d)", ret);
}

void RegisterConnectCallbackTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = RegisterConnectCallbacks(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]RegisterConnectCallbackTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = RegisterConnectCallbacks(g_sleConnectUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]RegisterConnectCallbackTestLevel1 failed2(%d)", ret);
    ret = RegisterConnectCallbacks(g_sleConnectUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]RegisterConnectCallbackTestLevel1 failed3(%d)", ret);
}

void SleConnectTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = SleConnect(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]SleConnectTestLevel1 failed1(%d)", ret);
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
    };
    ret = SleConnect(&remoteAddr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]SleConnectTestLevel1 failed2(%d)", ret);
}

void SendPairReqTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = SendPairReq(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]SendPairReqTestLevel1 failed(%d)", ret);
    SendPairReqTestLevel0();
}

void GetDevicePairStateTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
    };
    SlePairState pairState = SLE_PAIR_ERROR_STATE;
    ret = GetDevicePairState(NULL, &pairState);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]GetDevicePairStateTestLevel1 failed1(%d)", ret);
    ret = GetDevicePairState(&remoteAddr, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]GetDevicePairStateTestLevel1 failed2(%d)", ret);
    GetDevicePairStateTestLevel0();
}

void RemovePairTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = RemovePair(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]RemovePairTestLevel1 failed(%d)", ret);
    RemovePairTestLevel0();
}

void ReadRemoteRssiTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = ReadRemoteRssi(0xFFFF, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret != SLE_NO_ERROR, "[KhSleConnectTest][FAILED]ReadRemoteRssiTestLevel1 failed(%d)", ret);
}

void SleDisconnectTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = SleDisconnect(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]SleDisconnectTestLevel1 failed(%d)", ret);
    SleDisconnectTestLevel0();
}

void UnregisterConnectCallbackTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = UnregisterConnectCallbacks(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleConnectTest][FAILED]UnregisterConnectCallbackTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = UnregisterConnectCallbacks(g_sleConnectUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]UnregisterConnectCallbackTestLevel1 failed2(%d)", ret);
    ret = UnregisterConnectCallbacks(g_sleConnectUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]UnregisterConnectCallbackTestLevel1 failed3(%d)", ret);
}

void DeInitSleConnectServiceTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试重复调用
    ret = DeinitSleConnectService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]DeInitSleConnectServiceTestLevel1 failed1(%d)", ret);
    ret = DeinitSleConnectService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_NOT_READY, "[KhSleConnectTest][FAILED]DeInitSleConnectServiceTestLevel1 failed2(%d)", ret);
}

void KhSleConnectTestLevel1(void)
{
    SLE_UT_LOG("___KhSleConnectTestLevel1 start");
    InitSleConnectServiceTestLevel1();
    RegisterConnectCallbackTestLevel1();
    SleConnectTestLevel1();
    sleep(1);
    SendPairReqTestLevel1();
    sleep(1);
    GetDevicePairStateTestLevel1();
    RemovePairTestLevel1();
    sleep(1);
    ReadRemoteRssiTestLevel1();
    SleDisconnectTestLevel1();
    sleep(1);
    UnregisterConnectCallbackTestLevel1();
    DeInitSleConnectServiceTestLevel1();
    SLE_UT_LOG("___KhSleConnectTestLevel1 end");
}

SleErrorCode InitKhSleConnectTestEntry(void)
{
    g_sleConnectUtCbs = (SleConnectCallbacks *)malloc(sizeof(SleConnectCallbacks));
    SLE_UT_CHECK_AND_RETURN_RET(g_sleConnectUtCbs != NULL, SLE_ERR_SYSTEM_WRONG);
    g_sleConnectUtCbs->OnSleConnStateChangeCb = OnSleUtConnectStateChanged;
    g_sleConnectUtCbs->OnSleConnParamUpdatedCb = OnSleUtRequestConnParamUpdateCallback;
    return SLE_NO_ERROR;
}

SleErrorCode DeinitKhSleConnectTestEntry(void)
{
    free(g_sleConnectUtCbs);
    g_sleConnectUtCbs = NULL;
    return SLE_NO_ERROR;
}

void KhSleConnectTestEntry(void)
{
    SLE_UT_LOG("__KhSleConnectTestEntry start");
    SleErrorCode ret = InitKhSleConnectTestEntry();
    SLE_UT_CHECK_AND_RETURN_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]InitKhSleConnectTestEntry failed(%d)", ret);
    KhSleConnectTestLevel0();
    KhSleConnectTestLevel1();
    ret = DeinitKhSleConnectTestEntry();
    SLE_UT_CHECK_AND_RETURN_LOG(ret == SLE_NO_ERROR, "[KhSleConnectTest][FAILED]DeinitKhSleConnectTestEntry failed(%d)", ret);
    SLE_UT_LOG("__KhSleConnectTestEntry end");
}
